/**  
 * All rights Reserved, Designed By www.beonelot.com
 * @Package: com.bccah.modlib.dbdo.service.impl
 * @Filename: AcsControlUserInfoServiceImpl.java
 * @Description: TODO(AcsControlUserInfoService接口实现)
 * @author: 金鑫智慧
 * @date: 2020-04-08
 * @version: V1.0
 * @Copyright: 2018 www.beonelot.com Inc. All rights reserved.
 * 注意：本内容仅限于重庆金鑫智慧科技有限公司内部传阅，禁止外泄以及用于其他的商业目的
 */
package com.jinxin.platform.cdacsrecord.core.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.JsonObject;
import com.jinxin.platform.base.common.pojo.JsonResult;
import com.jinxin.platform.cdacsrecord.core.mapper.JurenAcsControlUserInfoMapper;
import com.jinxin.platform.cdacsrecord.core.mapper.JurenAcsControlUserMethodMapper;
import com.jinxin.platform.cdacsrecord.core.pojo.domains.*;
import com.jinxin.platform.cdacsrecord.core.pojo.entity.CommonCodeEntity;
import com.jinxin.platform.cdacsrecord.core.pojo.entity.Constant;
import com.jinxin.platform.cdacsrecord.core.pojo.entity.ResultEntity;
import com.jinxin.platform.cdacsrecord.core.pojo.vo.AcsControlUserInfoVO;
import com.jinxin.platform.cdacsrecord.core.pojo.vo.ResultVO2;
import com.jinxin.platform.cdacsrecord.core.redis.RedisUtil;
import com.jinxin.platform.cdacsrecord.core.service.*;
import com.jinxin.platform.cdacsrecord.core.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * TODO(AcsControlUserInfoService接口实现)
 * @Classn: AcsControlUserInfoServiceImpl
 * @author SY
 * @date 2020-04-08
 */
@Service
@Slf4j
@Transactional
public class AcsControlUserInfoServiceImpl extends BaseService implements AcsControlUserInfoService {

    @Resource
    private JurenAcsControlUserMethodMapper userMethodMapper;
    @Resource
    private JurenAcsControlUserInfoMapper userInfoMapper;
    @Resource
    private AcsControlAsyncService asyncService;
    @Autowired
    private RestTemplateService restTemplateService;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map delAcsUser(String uid,String companyId,String fafId) {
        Map<String,String> resMap =new HashMap<>();
        if(StringUtils.isEmpty(uid)){
            resMap.put("resultCode", CommonCodeEntity.PARAM_ERR);
            resMap.put("resultDesc", "用户id为空");
            return resMap;
        }
        AcsControlUserInfoDO infoDO = new AcsControlUserInfoDO();
        infoDO.setUserId(uid);
        infoDO.setCompanyId(companyId);
        infoDO.setUserFingerprint(fafId);
        ResultVO2 resultVO = restTemplateService.wyOwnerYcOperate(Constant.OPERATION_SIGN_DEL, infoDO);
        if(isSucceed(resultVO)){
            // 删除人脸照片  (接口问题暂时注释掉)
            //restTemplateService.removeFases(companyId,fafId);
            //删除用户表信息和用户访问方式表信息
            userInfoMapper.deleteByPrimaryKey(uid);
            userMethodMapper.delByUid(uid);
            resMap.put("resultCode", CommonCodeEntity.SUC_CODE);
            resMap.put("resultDesc", "suc");
        }else {
            resMap.put("resultCode", CommonCodeEntity.FAIL);
            resMap.put("resultDesc", "删除失败");
        }
        return  resMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map deleteMember(String uid,String companyId) {
        Map<String,String> resMap =new HashMap<>();
        if(StringUtils.isEmpty(uid) || StringUtils.isEmpty(companyId)){
            resMap.put("resultCode", CommonCodeEntity.PARAM_ERR);
            resMap.put("resultDesc", "用户id或小区id为空");
            return resMap;
        }
        AcsControlUserInfoDO infoDO = new AcsControlUserInfoDO();
        infoDO.setUserId(uid);
        infoDO.setCompanyId(companyId);
        ResultVO2 resultVO = restTemplateService.wyOwnerOperate(Constant.OPERATION_SIGN_DEL, infoDO);
        if(isSucceed(resultVO)){
            userInfoMapper.deleteByPrimaryKey(uid);
            resMap.put("resultCode", CommonCodeEntity.SUC_CODE);
            resMap.put("resultDesc", "suc");
        }else {
            resMap.put("resultCode", CommonCodeEntity.FAIL);
            resMap.put("resultDesc", "删除失败");
        }
        return  resMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map addAcsUser(AcsControlUserInfoVO infoVO, MultipartFile file) throws IOException {
        Map<String,String> resMap =new HashMap<>();
//        if(infoVO.getFile()!= null && !StringUtils.isEmpty(infoVO.getUserFaceInfo()) ){
//            if(ImageUtils.imageSize(infoVO.getUserFaceInfo())> 1024*50 ){
//                byte[] bytes = ImageUtils.commpressPicCycle(infoVO.getFile().getBytes(), 50, 0.5f);
//                BASE64Encoder encoder = new BASE64Encoder();
//                infoVO.setUserFaceInfo(encoder.encode(bytes));
//                log.info("imgsize:"+ ImageUtils.imageSize(infoVO.getUserFaceInfo()));
//            }
//        }
        AcsControlUserInfoDO infoDO = new AcsControlUserInfoDO();
        BeanUtils.copyProperties(infoVO,infoDO);
        infoDO.setState("0");
//        if( null != infoDO.getUserFaceInfo()){
//            infoDO.setUserFaceInfo(infoDO.getUserFaceInfo().replace(imgBase64Prefix,"") );
//        }
        if(StringUtils.isEmpty(infoDO.getUserId())){
            infoDO.setCreateTime(LocalDateTime.now());
            ResultVO2 resultVO = restTemplateService.wyOwnerYcOperate(Constant.OPERATION_SIGN_ADD, infoDO);
            if(isSucceed(resultVO)){
                String userId = resultVO.getObject().toString();
                infoDO.setUserId(userId);
                // 上传人脸到聚人平台
                if(file != null && !StringUtils.isEmpty(file.getOriginalFilename())){
                    File faceFile = UploadFileUtil.multipartFileToFile(file);
                    ResultVO2 faceResult = restTemplateService.extractFileFaceFeature("add", faceFile, infoDO.getCompanyId(), userId, "");
                    if(isSucceed(faceResult)){
                        String imgUrl = faceResult.getRstDesc();
                        String fafId = faceResult.getObject() != null ? String.valueOf(faceResult.getObject()) : "";
                        infoDO.setUserFaceInfo(imgUrl);
                        infoDO.setUserFingerprint(fafId);//指纹字段存的人脸照片id
                    }
                }
                userInfoMapper.insert(infoDO);
//                List<AcsControlUserInfoDO> userInfoDOList = new ArrayList<>();
//                userInfoDOList.add(infoDO);
//                asyncService.upUserMethodInfo(userInfoDOList);
                resMap.put("resultCode", CommonCodeEntity.SUC_CODE);
                resMap.put("resultDesc", "suc");
            }else {
                resMap.put("resultCode", CommonCodeEntity.FAIL);
                assert resultVO != null;
                resMap.put("resultDesc", resultVO.getRstDesc());
            }
        }else{
            ResultVO2 resultVO = restTemplateService.wyOwnerYcOperate(Constant.OPERATION_SIGN_EDIT, infoDO);
            if(isSucceed(resultVO)){
                if(file != null && !StringUtils.isEmpty(file.getOriginalFilename())){
                    File faceFile = UploadFileUtil.multipartFileToFile(file);
                    String fafId = infoDO.getUserFingerprint();
                    String operation = StringUtils.isEmpty(fafId) ? "add" : "edit";
                    ResultVO2 faceResult = restTemplateService.extractFileFaceFeature(operation, faceFile, infoDO.getCompanyId(), infoDO.getUserId(), fafId);
                    if(isSucceed(faceResult)){
                        String imgUrl = faceResult.getRstDesc();
                        String newFafId = faceResult.getObject() != null ? String.valueOf(faceResult.getObject()) : "";
                        infoDO.setUserFaceInfo(imgUrl);
                        infoDO.setUserFingerprint(newFafId);//指纹字段存的人脸照片id
                    }
                }
                userInfoMapper.updateByPrimaryKeySelective(infoDO);
                resMap.put("resultCode", CommonCodeEntity.SUC_CODE);
                resMap.put("resultDesc", "suc");
            }else {
                resMap.put("resultCode", CommonCodeEntity.FAIL);
                assert resultVO != null;
                resMap.put("resultDesc", resultVO.getRstDesc());
            }
        }
        return  resMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map addMember(AcsControlUserInfoVO infoVO, MultipartFile file){
        Map<String,String> resMap =new HashMap<>();
        AcsControlUserInfoDO infoDO = new AcsControlUserInfoDO();
        BeanUtils.copyProperties(infoVO,infoDO);
        infoDO.setState(Constant.USER_AUDIT_STATUS_OK);// TODO 审核通过
        if(StringUtils.isEmpty(infoDO.getUserId())){
            infoDO.setCreateTime(LocalDateTime.now());
            ResultVO2 resultVO = restTemplateService.wyOwnerOperate(Constant.OPERATION_SIGN_ADD, infoDO);
            if(isSucceed(resultVO)){
                String userId = resultVO.getObject().toString();
                infoDO.setUserId(userId);
                // 上传人脸到聚人平台
                if(file != null && !StringUtils.isEmpty(file.getOriginalFilename())){
                    File faceFile = UploadFileUtil.multipartFileToFile(file);
                    ResultVO2 faceResult = restTemplateService.extractFileFaceFeature("add", faceFile, infoDO.getCompanyId(), userId, "");
                    if(isSucceed(faceResult)){
                        String imgUrl = faceResult.getRstDesc();
                        String fafId = faceResult.getObject() != null ? String.valueOf(faceResult.getObject()) : "";
                        infoDO.setUserFaceInfo(imgUrl);
                        infoDO.setUserFingerprint(fafId);//指纹字段存的人脸照片id
                    }
                }
                userInfoMapper.insert(infoDO);
                resMap.put("resultCode", CommonCodeEntity.SUC_CODE);
                resMap.put("resultDesc", "suc");
            }else {
                resMap.put("resultCode", CommonCodeEntity.FAIL);
                assert resultVO != null;
                resMap.put("resultDesc", resultVO.getRstDesc());
            }
        }else{
            ResultVO2 resultVO = restTemplateService.wyOwnerOperate(Constant.OPERATION_SIGN_EDIT, infoDO);
            if(isSucceed(resultVO)){
                if(file != null && !StringUtils.isEmpty(file.getOriginalFilename())){
                    File faceFile = UploadFileUtil.multipartFileToFile(file);
                    String fafId = infoDO.getUserFingerprint();
                    String operation = StringUtils.isEmpty(fafId) ? "add" : "edit";
                    ResultVO2 faceResult = restTemplateService.extractFileFaceFeature(operation, faceFile, infoDO.getCompanyId(), infoDO.getUserId(), fafId);
                    if(isSucceed(faceResult)){
                        String imgUrl = faceResult.getRstDesc();
                        String newFafId = faceResult.getObject() != null ? String.valueOf(faceResult.getObject()) : "";
                        infoDO.setUserFaceInfo(imgUrl);
                        infoDO.setUserFingerprint(newFafId);//指纹字段存的人脸照片id
                    }
                }
                userInfoMapper.updateByPrimaryKeySelective(infoDO);
                resMap.put("resultCode", CommonCodeEntity.SUC_CODE);
                resMap.put("resultDesc", "suc");
            }else {
                resMap.put("resultCode", CommonCodeEntity.FAIL);
                assert resultVO != null;
                resMap.put("resultDesc", resultVO.getRstDesc());
            }
        }
        return  resMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultEntity uploadUser(MultipartFile file, String community)throws Exception {
        List<String[]> products = POIUtil.readExcel(file, 13);//人脸不支持导入
        int succeedCount1 = 0,succeedCount2 = 0,failCount1 = 0, failCount2 = 0;
        for (String[] prod:products ){
            String[] productInfo = prod;
            if(StringUtils.isEmpty(productInfo[0]) || StringUtils.isEmpty(productInfo[1])){
                continue;
            }
            AcsControlUserInfoDO infoDO = new AcsControlUserInfoDO();
            infoDO.setCompanyId(community);
            infoDO.setUserType(productInfo[0].trim());
            infoDO.setUserName(productInfo[1].trim());
            infoDO.setGender(Integer.parseInt(productInfo[2].trim()));
            infoDO.setUserCardType(productInfo[3].trim());
            String idCardNo = productInfo[4].trim();
            infoDO.setUserCard(idCardNo);
            infoDO.setUserPhone(productInfo[5].trim());
            infoDO.setUserRoomId(productInfo[6].trim());
            infoDO.setUserRoomName(productInfo[9].trim()+"-"+productInfo[7].trim());
            infoDO.setUserBlockId(productInfo[8].trim());
            infoDO.setUserBlockName(productInfo[9].trim());
            infoDO.setHushaiConsistent(Integer.parseInt(productInfo[10].trim()));
            infoDO.setPartyMembership(Integer.parseInt(productInfo[11].trim()));
            if(IdCardUtil.isValidatedAllIdcard(idCardNo)){
                infoDO.setAge(Utils.getPersonAgeFromIdCard(idCardNo));
            }
            if(StringUtils.isEmpty(productInfo[12])){
                infoDO.setCreateTime(LocalDateTime.now());
                infoDO.setState("0");
                ResultVO2 resultVO = restTemplateService.wyOwnerYcOperate(Constant.OPERATION_SIGN_ADD, infoDO);
                if(isSucceed(resultVO)){
                    infoDO.setUserId(resultVO.getObject().toString());
                    userInfoMapper.insert(infoDO);
                    succeedCount1++;
                }else {
                    failCount1++;
                }
            }else {
                infoDO.setUserId(productInfo[12]);
                ResultVO2 resultVO = restTemplateService.wyOwnerYcOperate(Constant.OPERATION_SIGN_EDIT, infoDO);
                if(isSucceed(resultVO)){
                    userInfoMapper.updateByPrimaryKey(infoDO);
                    succeedCount2++;
                }else {
                    failCount2++;
                }
            }
        }
        String msg = "成功导入"+succeedCount1+"条，失败"+failCount1+"条，更新成功"+succeedCount2+"条，失败"+failCount2+"条";
        return new ResultEntity(CommonCodeEntity.SUC_CODE,msg,"" );
    }

    @Override
    public PageInfo<AcsControlUserInfoDO> selParamPage(int page, int size, String userType, String blockID, String roomId, String userName,String community,String parentId,String excludeType) {
        PageHelper.startPage(page,size);
        List<AcsControlUserInfoDO> list = userInfoMapper.selAllTable(userType, blockID, roomId, userName,community,parentId,excludeType);
        PageInfo<AcsControlUserInfoDO> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    @Override
    public List<AcsControlUserInfoDO> selAllParam(String userType, String blockID, String roomId, String userName,String community,String parentId,String excludeType) {
        return userInfoMapper.selAllTable(userType, blockID, roomId, userName,community,parentId,excludeType);
    }

    @Override
    public int saveDO(AcsControlUserInfoDO paramDO) {
        return userInfoMapper.insert(paramDO);
    }

    @Override
    public int updateDO(AcsControlUserInfoDO paramDO) {
        return userInfoMapper.updateByPrimaryKeySelective(paramDO);
    }

    @Override
    public int delDO(String pid) {
        return userInfoMapper.deleteByPrimaryKey(pid);
    }

    @Override
    public List<AcsControlUserInfoDO> selDOByInfo(AcsControlUserInfoDO paramDO, String blockIds) {
        if(!StringUtils.isEmpty(blockIds)){
            String[] blockIdArr = blockIds.split(",");
            if(paramDO == null){
                paramDO = new AcsControlUserInfoDO();
            }
            paramDO.setBlockIdArr(blockIdArr);
        }
        return userInfoMapper.selDOByInfo(paramDO);
    }

    @Override
    public List<AcsControlUserInfoDO> selAll() {
        return userInfoMapper.selAll();
    }

    @Override
    public AcsControlUserInfoDO selById(String id) {
        return userInfoMapper.selById(id);
    }

    @Override
    public AcsControlUserInfoDO selectOne(HashMap param) {
        return userInfoMapper.selectOne(param);
    }

    @Override
    public List<AcsControlUserInfoDO> selectAllUsers() {
        return userInfoMapper.selectAllUsers();
    }

    @Override
    public List<RoomDto> selectOwners() {
        return userInfoMapper.selectOwners();
    }

    @Override
    public List<Map> countUserByAgeRange() {
        return userInfoMapper.countUserByAgeRange();
    }

    @Override
    public List<Map<String, Integer>> countUserByType() {
        return userInfoMapper.countUserByType();
    }

    @Override
    public List<Map<String, Integer>> countUserByMType() {
        return userInfoMapper.countUserByMType();
    }

    @Override
    public List<Map<String, Integer>> countOldUserByAgeRange() {
        return userInfoMapper.countOldUserByAgeRange();
    }

    @Override
    public ResultEntity saveOrUpdate(AppIdSecretInfo appIdSecretInfo) {
        if(appIdSecretInfo != null){
//            String userInfo = invokeService.getLoginUserInfo();
//            String userAccount = userInfo != null && !userInfo.equals("null") ? JSONObject.parseObject(userInfo).get("userAccount").toString() : "";
//            if(StringUtils.isEmpty(userAccount)){
//                return new ResultEntity(CommonCodeEntity.NO_LOGIN,"未登录用户","");
//            }
            String key = "appid_secret";
            JsonObject json = new JsonObject();
            json.addProperty("appid",appIdSecretInfo.getAppid());
            json.addProperty("appsecret",appIdSecretInfo.getAppsecret());
            json.addProperty("phone",appIdSecretInfo.getPhone());
            boolean isSucceed = redisUtil.set(key, json.toString());
            if(isSucceed){
                return new ResultEntity(CommonCodeEntity.SUC_CODE, "保存成功","" );
            }else {
                return new ResultEntity(CommonCodeEntity.FAIL, "redis异常，保存失败","" );
            }
        }
        return new ResultEntity(CommonCodeEntity.PARAM_ERR, "参数异常，保存失败","" );
    }

    @Override
    public ResultEntity saveOrUpdateFre(DataSyncFrequency dataSyncFrequency) {
        if(dataSyncFrequency != null){
            JsonObject json = new JsonObject();
            json.addProperty("openSyncFre",dataSyncFrequency.getOpenSyncFre());
            json.addProperty("capSyncFre",dataSyncFrequency.getCapSyncFre());
            boolean isSucceed = redisUtil.set(Constant.DATA_SYNC_FREQUENCY, json.toString());
            if(isSucceed){
                return new ResultEntity(CommonCodeEntity.SUC_CODE, "保存成功","" );
            }else {
                return new ResultEntity(CommonCodeEntity.FAIL, "redis异常，保存失败","" );
            }
        }
        return new ResultEntity(CommonCodeEntity.PARAM_ERR, "参数异常，保存失败","" );
    }

    @Override
    public ResultEntity getSyncfFrequency() {
        String key = "data_sync_frequency";
        String jsonStr = (String)redisUtil.get(key);
        if(!StringUtils.isEmpty(jsonStr)){
            DataSyncFrequency dataSyncFrequency = JSONObject.parseObject(jsonStr, DataSyncFrequency.class);
            return new ResultEntity(CommonCodeEntity.SUC_CODE,"获取同步频率成功",dataSyncFrequency);
        }
        return new ResultEntity(CommonCodeEntity.FAIL,"获取同步频率失败","");
    }

    @Override
    public ResultEntity getAkInfoByUser() {
//        String userInfo = invokeService.getLoginUserInfo();
//        String userAccount = userInfo != null && !userInfo.equals("null") ? JSONObject.parseObject(userInfo).get("userAccount").toString() : "";
//        if(StringUtils.isEmpty(userAccount)){
//            return new ResultEntity(CommonCodeEntity.NO_LOGIN,"未登录用户","");
//        }
        String key = "appid_secret";
        String jsonStr = (String)redisUtil.get(key);
        if(!StringUtils.isEmpty(jsonStr)){
            AppIdSecretInfo appIdSecretInfo = JSONObject.parseObject(jsonStr, AppIdSecretInfo.class);
            return new ResultEntity(CommonCodeEntity.SUC_CODE,"获取配置信息成功",appIdSecretInfo);
        }
        return new ResultEntity(CommonCodeEntity.FAIL,"获取配置信息失败","");
//        AppIdSecretInfo appIdSecretInfo = null;
//        try {
//            appIdSecretInfo = (AppIdSecretInfo)SerializeUtil.deserialize((byte[]) redisUtil.get(key));
//        } catch (IOException e) {
//            e.printStackTrace();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//        return new ResultEntity(CommonCodeEntity.SUC_CODE,"获取配置信息成功",appIdSecretInfo);
    }

    @Override
    public JsonResult getFaceInfoById(String id) {
        if(StringUtils.isEmpty(id)){
            return JsonResult.error("用户id不存在");
        }
        AcsControlUserInfoDO userInfo = userInfoMapper.selById(id);
        if(userInfo == null){return JsonResult.ok("");}
        return JsonResult.ok(userInfo.getUserFaceInfo());
    }
}
